package com.hu.bgp.server;

import java.util.Date;
import java.util.UUID;

import com.hu.bgp.exceptions.CommonException;
import com.hu.bgp.framework.GameContext;
import com.hu.bgp.framework.GameState;
import com.hu.bgp.framework.ServerFacade;
import com.hu.bgp.framework.clientapi.ClientToServerMessage;
import com.hu.bgp.shared.LeaveMessage;

import de.novanic.eventservice.client.event.domain.DomainFactory;

public class GameInstance
{
	private GameType gameType;
	private GameContext gameContext;
	private UUID uuid;
	private ServerFacade server;
	private Date startDate;

	public GameInstance(GameType gameType, Player initialPlayer)
	{
		this.gameType = gameType;
		uuid = UUID.randomUUID();
		gameContext = new GameContext(DomainFactory.getDomain("gameDomain" + uuid.toString()), initialPlayer);
		try
		{
			server = (ServerFacade) gameType.getServerClass().getConstructor(GameContext.class).newInstance(gameContext);
		}
		catch (Exception e)
		{
			throw new CommonException("Could not instantiate game.");
		}
		System.out.println(String.format("GameInstance.GameInstance: created %s with uuid %s", gameType.getAlias(), uuid.toString()));
		initialPlayer.joinGame(this);
		startDate = new Date();
	}

	public GameType getGameType()
	{
		return gameType;
	}

	public GameContext getGameContext()
	{
		return gameContext;
	}

	public String getUuidString()
	{
		return uuid.toString();
	}

	public Date getStartDate()
	{
		return startDate;
	}

	public void handleMessage(ClientToServerMessage message, Player fromPlayer)
	{
		if (message instanceof LeaveMessage)
		{
			ejectPlayer(fromPlayer);
		}
		else
		{
			server.handleMessage(message, fromPlayer);
		}
	}

	public void joinPlayer(Player player)
	{
		if (gameContext.getState() == GameState.WAITING_FOR_PLAYERS)
		{
			gameContext.getPlayers().add(player);
			server.playerJoined(player);
		}
		else
		{
			throw new CommonException("Not waiting for players");
		}
	}

	public void ejectPlayer(Player player)
	{
		gameContext.getPlayers().remove(player);
		server.playerLeft(player);
	}

	public void rejoinPlayer(Player player)
	{
		gameContext.getPlayers().add(player);
		server.playerRejoined(player);
	}
}
